package server

import (
	"crypto/tls"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"path/filepath"
	"server/src/global"
	"time"
)

type serverTlS interface {
	ListenAndServeTLS(crt, key string) error
}
type server interface {
	ListenAndServe() error
}

func Initserver() {
	system := global.GVL_CFG.System
	r := InitRouters()
	if system.IsHttps {
		s := initTlSServer(system.Addr, r)
		time.Sleep(10 * time.Microsecond)
		global.GVL_LOG.Info("busi_cont TLS run success on ", zap.String("address", system.Addr))
		startTLSServer(s)
	} else {
		s := initServer(system.Addr, r)
		time.Sleep(10 * time.Microsecond)
		global.GVL_LOG.Info("busi_cont run success on ", zap.String("address", system.Addr))
		startServer(s)
	}
}

// 初始化TLSserver配置
func initTlSServer(address string, router *gin.Engine) serverTlS {
	cfg := &tls.Config{
		MinVersion:               tls.VersionTLS12,
		CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
		PreferServerCipherSuites: true,
		CipherSuites: []uint16{
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		},
	}
	return &http.Server{
		Addr:           address,
		Handler:        router,
		ReadTimeout:    20 * time.Second,
		WriteTimeout:   20 * time.Second,
		MaxHeaderBytes: 1 << 20,
		TLSConfig:      cfg,
		TLSNextProto:   make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
	}
}

// 初始化server配置
func initServer(address string, router *gin.Engine) server {
	cfg := &tls.Config{
		MinVersion:               tls.VersionTLS12,
		CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
		PreferServerCipherSuites: true,
		CipherSuites: []uint16{
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		},
	}
	return &http.Server{
		Addr:           address,
		Handler:        router,
		ReadTimeout:    20 * time.Second,
		WriteTimeout:   20 * time.Second,
		MaxHeaderBytes: 1 << 20,
		TLSConfig:      cfg,
		TLSNextProto:   make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
	}
}

// 开始运行server
func startServer(s server) {
	global.GVL_LOG.Error(s.ListenAndServe())

}

func startTLSServer(s serverTlS) {
	//https，放置nign的tsl证书
	cerFile, err := filepath.Abs(global.GVL_CFG.System.CerFile)
	keyFile, err := filepath.Abs(global.GVL_CFG.System.KeyFlie)
	if err != nil {
		panic(any(errors.New(fmt.Sprintln(".key和.crt:" + err.Error()))))
	}
	global.GVL_LOG.Error(s.ListenAndServeTLS(cerFile, keyFile).Error())
}
